import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;


public class RegistryServer extends Thread{ 

	private ServerSocket socket;
	private ConfigurationManager propertymanager;
	private static Logger log;
	private List<Thread> listServerThreads;
	private Boolean shutdown = false;
	
	private void init() throws IOException
	{
		log = Logger.getLogger();
		
		propertymanager = ConfigurationManager.getPropertyManager();
		int port = propertymanager.getPortNumber();
		socket = new ServerSocket(port);
		listServerThreads = new ArrayList<Thread>();
		log.info("Started Server: " + socket.toString());
		
	}
	
	private  void addServerThread(Socket sock) throws IOException
	{
		log.info("Connection accepted from " + sock);
		Thread serverThread = new ServerThread(sock, this);
		listServerThreads.add(serverThread);
		log.info("Running Server Thread:" + sock);
		serverThread.start();
	}
	
	public synchronized void shutdown()
	{
		/*You can only set it to true. */
		shutdown = true; 
		/*Kill the socket*/
		try{
			socket.close(); /*Stop main thread from listening on socket*/
		   }catch(IOException ioe)
			{
				log.error(" 0x004 IOEXception on closing ServerSocket:" + ioe );
			}
	}
	
	public synchronized void removeServerThread(ServerThread thread) 
	{
		listServerThreads.remove(thread);
		log.info("Thread Removed.Remaining :" + listServerThreads.size());
	}
	
	public void srun() throws IOException
	{
		while(true)
		{
			log.info("Waiting for a connection...");
			try{
				if(!shutdown)
				{	
					Socket sock = socket.accept();
					addServerThread(sock);
				}
			}catch (SocketException except)
			{ 
				/* You only get here if the blocking call of socket is interrupted , so quit the server. */
				while(listServerThreads.size()!=0)
				{
					try{
						Thread.sleep(500);
					}catch(InterruptedException ie) {}
				}
				return;
			}
			
		}
			
	}
	
	
public void run() 
{
	try {
			try{
				init();
			}catch (IOException e)
			{
				log.error("0x001 - Port Already in Use");
				return ;
			}
			srun();
			log.info("Exiting Server");
		}catch (IOException e)
		{	
			log.error("0x004  Irrecoverable IOException :  " + e);
		}
}

}
